/*
ID: icerupt1
PROG: tour
LANG: C++11
*/

/* solution
 *
 * good problem.
 * 费用流的话很好理解，就是一个最大流为2的流网络，每条流对应一条路径。
 * 将每个点设置一个-1的费用（拆点）跑最小费用最大流，最小费用取负就是最多
 * 可以到达的城市数。O(F|E|log|V|)。
 *
 * 还有dp的做法，用f[i][j]表示两条路分别以i, j结尾，转移的时候很巧妙，
 * 保证不重复经过点就好。
 *
 * 好像有点像 双调欧几里得旅行商问题。
 * 
*/
#include <fstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <string>
#include <vector>
#include <queue>
#include <utility>

std::ifstream fin {"tour.in" };
std::ofstream fout{"tour.out"};

typedef std::pair<int, int> P;
struct edge {int to, cap, cost, rev; };

int const MAX_V = 217;
int const INF = 1<<27;
int V;
std::vector<edge> G[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, int cost)
{
	G[from].push_back((edge){to, cap, cost, (int)G[to].size()});
	G[to].push_back((edge){from, 0, -cost, (int)G[from].size() - 1});
}

int min_cost_flow(int s, int t, int f)
{
	int res = 0;
	std::fill(h, h + V, 0);
	while (f > 0) {
		std::priority_queue<P, std::vector<P>, std::greater<P>> que;
		std::fill(dist, dist + V, INF);
		dist[s] = 0;
		que.push(P(0, s));
		while (!que.empty()) {
			P p = que.top(); que.pop();
			int v = p.second;
			if (dist[v] < p.first) continue;
			for (int i = 0; i < (int)G[v].size(); i++) {
				edge & e = G[v][i];
				if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
					dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
					prevv[e.to] = v;
					preve[e.to] = i;
					que.push(P(dist[e.to], e.to));
				}
			}
		}
		if (dist[t] == INF) return -1;
		for (int v = 0; v < V; v++) h[v] += dist[v];

		int d = f;
		for (int v = t; v != s; v = prevv[v])
			d = std::min(d, G[prevv[v]][preve[v]].cap);
		f -= d;
		res += d * h[t];
		for (int v = t; v != s; v = prevv[v]) {
			edge & e = G[prevv[v]][preve[v]];
			e.cap -= d;
			G[v][e.rev].cap += d;
		}
	}
	return -res;
}

int n, m;

int main()
{
	std::unordered_map<std::string, int> index;
	fin >> n >> m;
	for (int i = 1; i <= n; i++) {
		std::string s;
		fin >> s;
		index[s] = i;
		if (i > 1 && i < n) add_edge(2*i - 1, 2*i, 1, -1);
	}
	int super_s = 0, s = 1, t = 2 * n + 1;
	V = t + 1;
	add_edge(super_s, s, 2, 0);
	add_edge(s, s+1, 2, 0);
	add_edge(t-1, t, 2, 0);
	add_edge(t-2, t-1, 2, 0);
	for (int i = 0; i < m; i++) {
		std::string s1, s2;
		fin >> s1 >> s2;
		int t1 = index[s1], t2 = index[s2];
		if (t1 > t2) std::swap(t1, t2);
		add_edge(2*t1, 2*t2 - 1, 1, 0);
	}
	int ans = min_cost_flow(super_s, t, 2);
	ans += 2;

	std::cout << ans << '\n';
	fout << ans << '\n';
}

